
require "Common/define"
require "Logic/CtrlManager"
require "Logic/Config"
require "model/ErrorCode"
require "proto/login/message/ReqLoginUserMessage"
require "proto/login/message/ReqReconnectMessage"
require "proto/login/message/ReqLoginSceneServerMessage"
require "model/MercenaryModel"

G = G or {};
loginHandler = loginHandler or {};
local serverData = serverData or {};
G.serverData = serverData or {};

--- 服务器完成数据全同步的通知
function loginHandler.receiveLoginSyncFinish()
    Config.SyncAttrAllFinish = true
	print("SyncAttrAllFinish is true")
end


--选择角色进入游戏
function loginHandler.receiveLoginPlayerSuccess(msg)
    if Game.reConnect then
        Game.reConnect = false;
		print("reconnect finished");
        return;
    end
	Config.chatServerId = msg.showServerId or 0;
    --加载Loading，进入游戏
    showUI(PanelNames.UILoading);
end

--顶号
function loginHandler.receiveSubstituteUser(msg)
    G.serverData = {};
    --断开连接
    WebMsgMgr:DisConnect();
    --IMAudioMgr:logoutIMSystem();
    MercenaryModel.mercenSotreList = {};
    MercenaryModel.partnerFormates= {};
    UILoading.mapLoadFinish = false;
    MercenaryModel.resetData();
    if FightManager.fightBegin then
        UIRoundBattle.forceClose();
    end
    --mapMgr:pauseByGuide(0);
    --mapMgr:setViewInit(0);
    WebSocketMgr.GetInstance():Close();
    RedDotsManager.Clear()
    --隐藏所有UI
    closeAllUI()

    --清空场景数据
    --mapMgr:ClearScene();
    MercenaryModel.resetMercenary();
    collectgarbage("collect");

    --显示login界面
    showUI(PanelNames.UILogin)
    UISysTips.AddMsg("您的账号在其他设备登录");

    --GuildWarManager.Reset()

    Game.sendPingTime = 0;

end

--错误信息
function loginHandler.onErrorCode(msg)
    local errorid = msg.state;
	log("errorid===="..errorid)
    UIWaiting.HideWaiting();
    NetMsgDecoder.hasSendMsgOrder = {};
    if(ErrorCode[errorid] ~= nil) then
        --UISysTips.AddMsg(ErrorCode[errorid]);
        print(ErrorCode[errorid]);
    end

	if errorid == 10004 then
		ConnectManager.Back2Login()
	end
end

-- 开服时间
function loginHandler.onServerInfoNotice(msg)
	logicMgr.LoginManager.setServerStartTime(msg.startTime);
end

function loginHandler.getAnnouncement(callback)
    local paramdata = {};
    WebMsgMgr:SendHttpRequest(logicMgr.LoginManager.GetHttpServerUrl().."announcement/get",getJsonStr(paramdata),callback);
end

--解析公告
function loginHandler.decode_notice(p)
	local size = WebMsgMgr:readByte(p);
	local data = {};
	local sub = {};
	for i=1,size do	
		local arr = {};
		arr["title"] = WebMsgMgr:readString(p);
		arr["bulletin"] = WebMsgMgr:readString(p);
		table.insert(sub,arr);	
	end
	data["notice"] = sub;
	data["url1"] = WebMsgMgr:readString(p);
	data["url2"] = WebMsgMgr:readString(p);
	data["updateUrl"] = WebMsgMgr:readString(p);

	G.serverData["notice"] = data;
	return data;
end

--请求连接gameserver
function loginHandler.decode_connectGame( p )
	data = {};
	local opt = WebMsgMgr:getOpt(p)
	data["opt"] = opt
	if opt == 0 then
		data["serverId"] = WebMsgMgr:readInt(p)
		data["address"] = WebMsgMgr:readString(p)
		data["port"] = WebMsgMgr:readInt(p)
		data["protag"] = WebMsgMgr:readShort(p)
		data["isReConn"] = WebMsgMgr:readByte(p)
		data["loginId"] = WebMsgMgr:readInt(p)
		data["verifyStr"] = WebMsgMgr:readString(p)

	elseif opt == 2 or opt == 3 or opt ==4 or opt ==6 then
		data["isBind"] = WebMsgMgr:readByte(p)
		local areaCount = WebMsgMgr:readByte(p)

		local sub={}
		for i=1,areaCount do
			local areaArr = {}
			areaArr["areaName"] = WebMsgMgr:readString(p)
			local serverCount = WebMsgMgr:readByte(p)
			local servertable = {}
			for i=1,serverCount do
				local serverArr = {}
				serverArr["serverId"] = WebMsgMgr:readInt(p)
				serverArr["serverName"] = WebMsgMgr:readString(p)
				serverArr["state"] = WebMsgMgr:readByte(p)
				table.insert(servertable,serverArr)
			end
			areaArr["serverArr"] = servertable
			table.insert(sub,areaArr)
		end
		data["areaList"] = sub
		data["error"] = 1;
	else 
		data["error"] = 1;
	end

	G.serverData["connectInfo"] = data;
	if G._ConnectServer ~= nil then
		G._ConnectServer();
		return nil;
	end
	
	
	return data;
end

--- 登录服务器验证 使用post请求 Http.Get R_HttpU8Loing
function loginHandler.R_HttpVerifyLogin(platform, jsonStr, callback)
	local url = ""
	local platformName = ""
	local loginUrl;
	local serverUrl = logicMgr.LoginManager.GetLoginServerUrl();
	if serverUrl ~= nil then
		loginUrl = serverUrl .. "/v1/api/login"
	end
	if loginUrl == nil then
		return ;
	end
	if platform == EnumConst.LoginPlatform.PC then
		url = loginUrl..EnumConst.LoginUrl.Default
		platformName = EnumConst.LoginPlatform.PC
	elseif platform == EnumConst.LoginPlatform.U8 then
		url = loginUrl..EnumConst.LoginUrl.U8SDK
		platformName = EnumConst.LoginPlatform.U8
	end
    logicMgr.LoginManager.SetLoginPlatform(platformName)

	print("====登录验证====", url, getJsonStr(jsonStr))
	Http.httpReqTimeOut = 8
	Http.Get(url, jsonStr, callback)
end

--- 爆满时重新获取推荐服务器
function loginHandler.R_HttpLoginWhenFull(callback)
	local url = ""
	local loginUrl;
	local serverUrl = logicMgr.LoginManager.GetLoginServerUrl();
	if serverUrl ~= nil then
		loginUrl = serverUrl .. "/v1/api/login"
	end
	if loginUrl == nil then
		return ;
	end
	local platform = logicMgr.LoginManager.GetLoginPlatform();
	local curPlatform;
	if platform == EnumConst.LoginPlatform.PC then
		url = loginUrl..EnumConst.LoginUrl.U8SDK.."reLoginWhenFull/"; -- 暂时先这样
		curPlatform = "dev";
	elseif platform == EnumConst.LoginPlatform.U8 then
		url = loginUrl..EnumConst.LoginUrl.U8SDK.."reLoginWhenFull/";
		curPlatform = "U8";
	end

	local curUserId = tostring(AppConst.UserId);
	local arr = string.split(curUserId, ":");
	local strNum = #arr;
	local userName;
	if strNum > 1 then
		userName = arr[2];
		for i = 3, strNum do
			userName = userName..arr[i];
		end
	end
	local jsonStr =
	{
		userId = userName,
		token = G.serverData.token,
		platform= curPlatform,
		deviceId = SystemInfo.deviceUniqueIdentifier
	}
	print("====爆满时重新获取推荐服务器====", url, getJsonStr(jsonStr))
	YanhuaMMO.Http.httpReqTimeOut = 8
	Http.Get(url, jsonStr, callback)
end

--- 步骤2 平台登录
function loginHandler.R_LoginUser()
	local isLogin = logicMgr.LoginManager.getLoginState();
	if isLogin ~= nil and isLogin then
		return;
	end
	logicMgr.LoginManager.setLoginSate(true);
	logicMgr.LoginManager.RefreshLoginUserTime();
	local osType = 0
	if (Application.platform == RuntimePlatform.Android) then
		osType = 1
	elseif (Application.platform == RuntimePlatform.IPhonePlayer) then
		osType = 2
	end

	Config.SendLoginTime = os.time()
	Config.LoginSuccess = false
	local req = ReqLoginUserMessage.New();
	req.token =  G.serverData.token;
	req.deviceId = SystemInfo.deviceUniqueIdentifier
	req.platform = logicMgr.LoginManager.GetLoginPlatform();
	req.serverId = AppConst.ServerId;
	req.osType = osType;
	req.appVersion = tostring(LoginManager.GetVersionInt(YanhuaMMO.AppConst.appVersion));
	sendReqMessage(req);
end

--- 角色创建
function loginHandler.R_CreatePlayer(name, country, serverId)
    local createmsg =  ReqCreatePlayerMessage.New()
	local osType = 0
	if (Application.platform == RuntimePlatform.Android) then
		osType = 1
	elseif (Application.platform == RuntimePlatform.IPhonePlayer) then
		osType = 2
	end
    createmsg.playerName = name
    createmsg.country = country or 1
	createmsg.serverId = serverId or 1
	createmsg.deviceId = SystemInfo.deviceUniqueIdentifier;
	createmsg.distinctId = TA.TABehavior.GetDistinctId()
	createmsg.subChannel = tostring(Config.SDK_SubChannel)
	createmsg.osType = osType;
	createmsg.appVersion = tostring(LoginManager.GetVersionInt(YanhuaMMO.AppConst.appVersion));
	sendReqMessage(createmsg)
end

--- 登录返回
function loginHandler.S_LoginUser(msg)
	--1没有角色 2有角色
	Config.LoginSuccess = true;
	logicMgr.LoginManager.removeLoginUserTime();
	logicMgr.LoginManager.setLoginSate(false);
	print("relogin success");
	local code = tonumber(msg.state);
	if code == 10001 then
		local showLoginTipsType = 1;
		local tips = "Sys_MsgServerFull";
		if Config.lastLoginServerId > 0 then
			showLoginTipsType = 2;
			tips = "Sys_MsgServerFullAndReturn";
		end
		logicMgr.LoginManager.showLoginTips(tips, function()
			loginHandler.loginUserAgain();
		end, showLoginTipsType);
		return ;
	end
	if code ~= 0 then
		UISysTips.AddMsgErrorCode(msg.state);
		return ;
	end

	local login = CtrlManager.GetCtrl(PanelNames.UILogin);
	if login ~= nil then
		-- msg.banned = 1
		-- msg.bannedType = 1
		-- msg.bannedEndTime = os.time()
		LoginManager.SetBannedState(msg)
		-- login:onLoginUserSucess(msg.existCharater == 2);
		LoginManager.SetServerOpenTime(msg.serverOpenTime);
		if msg.banned == 1 then
			local tt = tonumber(tostring(msg.bannedEndTime))
			local timestr = os.date("%Y-%m-%d %H:%M", tt / 1000)
			LoginManager.LoginShowException(msg.bannedType, timestr)
		else
			login:onLoginUserSucess(msg.existCharater == 2);
		end
		if isOpenUI(PanelNames.UILoginTips) then
			closeUI(PanelNames.UILoginTips);
		end
	end
end

function loginHandler.loginUserAgain()
	local login = CtrlManager.GetCtrl(PanelNames.UILogin);
	if login ~= nil then
		if Config.lastLoginServerId > 0 then
			login:updateServerId();
			if logicMgr.LoginManager.GetLoginPlatform() == EnumConst.LoginPlatform.PC then
				login:onEnterClick();
			elseif logicMgr.LoginManager.GetLoginPlatform() == EnumConst.LoginPlatform.U8 then
				login:httpVerifyLoginU8();
			end
		else
			if logicMgr.LoginManager.GetLoginPlatform() == EnumConst.LoginPlatform.PC then
				login:httpLoginWhenFullU8();
			elseif logicMgr.LoginManager.GetLoginPlatform() == EnumConst.LoginPlatform.U8 then
				login:httpLoginWhenFullU8();
			end
		end
	end
end

--- 获取已存在角色的服务器列表
function loginHandler.HttpGetServerUserList(callback)
    local function funcCallBack(result, data)
		print("result===", result, data)
        if result then
            if callback then
				print(data)
                callback(decodeJsonStrToTabel(data))
            end
        else
			--UISysTips.AddMsg("获取不到服务器列表")
            print("http get recommend service is error !")
        end
    end
	local url;
	local serverUrl = logicMgr.LoginManager.GetLoginServerUrl();
	if serverUrl == nil then
		callback({});
		return;
	end
	url = serverUrl.."/server/record/";
	local platform;
	if logicMgr.LoginManager.GetLoginPlatform() == EnumConst.LoginPlatform.PC then
		platform = "dev";
	else
		platform = "U8";
	end
	local curUserId = tostring(AppConst.UserId);
	local arr = string.split(curUserId, ":");
	local strNum = #arr;
	local userName;
	if strNum > 1 then
		userName = arr[2];
		for i = 3, strNum do
			userName = userName..arr[i];
		end
	end
    local jsonStr =
    {
        username = userName,
		platform= platform
    }
    print("====已存在角色的服务器列表====", getJsonStr(jsonStr))
    Http.Get(url, jsonStr, funcCallBack)
end

--获取预开服时间
function loginHandler.HttpGetNoticeServerTime(callback)
	logicMgr.LoginManager.SetNoticeServerTime()
	Http.Get(Config.NOTICE_SERVER_OPENTIME_URL,"",function (success, noticeServerTime)
		if success then
			local noticeServerTime = tonumber(decodeJsonStrToTabel(noticeServerTime)) or 0
			logicMgr.LoginManager.SetNoticeServerTime(noticeServerTime)
		end
		if callback then
			callback()
		end
	end)
end

--- 重连
function loginHandler.R_Reconnect(token)
	local req = ReqReconnectMessage.New()
	req.token = token or G.serverData.token   --TODO G.serverData最好干掉  统一到LoginManager里进行管理
	if isOpenUI(PanelNames.UIRankBattleTeam) or isOpenUI(PanelNames.UIRankBattleMatching) then
		req.showShowType = 1
	else
		req.showShowType = 0
	end
	sendReqMessage(req)
	print("发送重连");
	UIWaiting.WaitingShow()
end

--- 心跳
function loginHandler.R_Heart()
	local req = ReqHeartMessage.New()
	req.version = Config.ProtoVersion
	if Game.sendPingTime == 0 then
		Game.sendPingTime = os.time()
	end
	sendReqMessage(req,0)
end
---------------------公会战------------开始----
---- 登录战场服返回
function loginHandler.S_LoginUnionWar(msg)
	if msg.state == 0 then
		--UIWaiting.WaitingShow()
		loginHandler.UnionWarMsg = msg;
		loginHandler.isLoginedSceneServer = true;
		print("开始连接",msg.host,msg.port)
		loginHandler.R_ConnectUnionWar()
		if msg.roomId then
			logicMgr.DarkStreetMgr.room_id = tostring(msg.roomId)
			logicMgr.DarkStreetMgr.Track_enterSuccess()
		end
	end
end

--- 连接战场服
function loginHandler.R_ConnectUnionWar()
	if loginHandler.UnionWarMsg == nil then
		return ;
	end
	--WebMsgMgr:SceneDisConnect();

		WebMsgMgr:ConnectSceneServer(loginHandler.UnionWarMsg.host, loginHandler.UnionWarMsg.port, "", "", function(result, resulInfo)
			--UIWaiting.WaitingHide()
			if result ~= false then
				print("Scoket链接成功")
				loginHandler.R_LoginUnionWar(loginHandler.UnionWarMsg.token);
			else
				UISysTips.AddMsg(getLanguage("Sys_MsgNetworkError"))
				printError("Scoket链接失败")
			end
		end)
end
--- 登陆战场服
function loginHandler.R_LoginUnionWar(token)
	local req = ReqLoginSceneServerMessage.New()
	req.token = token or G.serverData.token;
	sendSceneReqMessage(req)
	print("请求登陆战场服")
end
--- 服务端回复战场服登录结果
function loginHandler.S_LoginUser2(msg)
	if msg.state == 0 then
		loginHandler.isLoginedSceneServer = true;
		loginHandler.loginSucceedStartHeart()
	end
end
---战场服通知客户端,返回游戏服(例如活动结束等待各种情况),服务器发送完这个消息就会把他战场服的socket给关闭
function loginHandler.ResBackGameHandler(msg)
	loginHandler.R_LeaveUnionWar();
end

---连接成功开始发送心跳和重连保护
function loginHandler.loginSucceedStartHeart()
	loginHandler.R_Heart2();
	if loginHandler.UnionWarUTime then
		utimer.remove(loginHandler.UnionWarUTime);
		loginHandler.UnionWarUTime = nil;
	end
	if loginHandler.UnionWarHeartUTime then
		utimer.remove(loginHandler.UnionWarHeartUTime)
		loginHandler.UnionWarHeartUTime = nil
	end
	loginHandler.UnionWarUTime = utimer.timeCall( function()
		loginHandler.R_Heart2();
	end, 3000, -1);
	loginHandler.UnionWarHeartNum = 0; -- 战场服连续未收到回复的心跳次数
	if loginHandler.UnionWarHeartUTime == nil then
		loginHandler.sceneServerReconnectNum = 0; -- 战场服断线重连次数
		loginHandler.UnionWarHeartUTime = utimer.timeCall( function()
			loginHandler.UnionWarHeartNum = loginHandler.UnionWarHeartNum + 1;
			if loginHandler.UnionWarHeartNum >= 20 and loginHandler.UnionWarHeartNum % 5 == 0 then
				loginHandler.sceneServerReconnectNum = loginHandler.sceneServerReconnectNum + 1;
				if loginHandler.sceneServerReconnectNum > 3 then
					UISysTips.AddMsg("网络重连失败,请稍后再试")
					FireEvent(Config.EventType.Fresh_SceneServerReconnectFail);
					return ;
				end
				local req = ReqReconnectMessage.New()
				req.token = loginHandler.UnionWarMsg.token
				req.showShowType = 0
				sendSceneReqMessage(req)
				UIWaiting.WaitingShow()
			end
		end, 1000, -1);
	end
end

--- 心跳
function loginHandler.R_Heart2()
	local req = ReqHeartMessage.New()
	req.version = Config.ProtoVersion;
	sendSceneReqMessage(req,0);
end

--- 战场服务器回复当前角色的所在地图
function loginHandler.S_LoginPlayerSuccess2(msg)
	local xx = 1;
end

--- 战场服返回重连
function loginHandler.S_Reconnect2(msg)
	if msg.state == 0 then
		UIWaiting.WaitingHide()
		loginHandler.sceneServerReconnectNum = 0;
		loginHandler.UnionWarHeartNum = 0;
	else
		print("重连战场服失败")
	end
end

--- 战场服的心跳消息
function loginHandler.S_Heart2(msg)
	if msg.state == 0 then
		loginHandler.UnionWarHeartNum = 0;
	else
		print("心跳版本错误")
	end
end

--- 断开战场服连接
function loginHandler.R_LeaveUnionWar()
	log("已断开战场服连接")
	WebMsgMgr:SceneDisConnect();
	loginHandler.isLoginedSceneServer = false;
	if loginHandler.UnionWarUTime then
		utimer.remove(loginHandler.UnionWarUTime);
		loginHandler.UnionWarUTime = nil;
	end
	if loginHandler.UnionWarHeartUTime then
		utimer.remove(loginHandler.UnionWarHeartUTime);
		loginHandler.UnionWarHeartUTime = nil;
	end
end
---------------------公会战------------结束----